/*
 * Copyright 2003-2005 (c) Live Media Pty Ltd. <argot@einet.com.au> 
 *
 * This software is licensed under the Argot Public License 
 * which may be found in the file LICENSE distributed 
 * with this software.
 *
 * More information about this license can be found at
 * http://www.einet.com.au/License
 * 
 * The Developer of this software is Live Media Pty Ltd,
 * PO Box 4591, Melbourne 3001, Australia.  The license is subject 
 * to the law of Victoria, Australia, and subject to exclusive 
 * jurisdiction of the Victorian courts.
 */

#include <Types.h>
#include <dictionary/Dictionary.h>
#include <dictionary/DictionaryTypes.h>
#include <TypeBindCommon.h>
#include <DynamicTypeMap.h>

#include <network/TypeTriple.h>
#include <network/TypeLink.h>
#include <network/ProtocolTypeMap.h>
#include <network/TypeClient.h>
#include <network/TypeServer.h>
#include <network/DynamicClientTypeMap.h>

#include <common/BigEndianUnsignedByte.h>
#include <common/BigEndianSignedInteger.h>
#include <common/BigEndianUnsignedInteger.h>

#include <util/chunkbuffer.h>
#include <message/MessageReader.h>
#include <message/MessageWriter.h>

#include "../data/MixedData.h"
#include "TypeNetworkTest.h"

CPPUNIT_TEST_SUITE_REGISTRATION( TypeNetworkTest );


/* helpers file readers */
typedef struct file_data
{
	FILE * fd;
}
file_data;


static int fileReader( type_input_stream * in, void * data, char * buffer, int size )
{
	file_data * fileData = (file_data *) data;

	return fread( buffer, 1, size, fileData->fd );	
}


void TypeNetworkTest::setUp()
{
	file_data fileData;
	reference_type_map core_map;
	type_map dictionary_map;
	int rc;
	
	type_library_init( &_library ); 
	rc = type_core_init( &_library );
	if ( rc != TYPE_OK )
	{
		printf( "failed to init core" );
		return;
	}
	
	rc = dictionary_types_init( &_library );
	if ( rc != TYPE_OK )
	{
		printf( "failed to init dictionary" );
		return;
	}
	
	reference_type_map_init( &core_map, &_library, NULL );
	type_map_core_init( &core_map );

	fileData.fd = fopen( "data\\common.dictionary","r" );
	if ( fileData.fd == NULL )
	{
		printf( "common.dictionary not found" );
		return;
	}
	
	type_map_init( &dictionary_map, &_library );
	
	rc = read_dictionary( &_library, fileReader, &fileData, &dictionary_map );
	if (rc != TYPE_OK )
	{
		printf( "failed to read meta.dictionary" );
		return;
	}
	
	rc = type_bind_common( &_library );
	if ( rc != TYPE_OK )
	{
		printf( "failed to bind common types\n" );
		return;
	}
	
	rc = mixed_data_register( &_library );
	if ( rc <= NOTYPE )
	{
		printf( "failed to register mixed data\n" );
		return;
	}

}

void TypeNetworkTest::testClientResolutionGetIdName()
{
	dynamic_type_map serverMap;
	type_server typeServer;
	type_client typeClient;
	dynamic_client_type_map clientMap;
	
	dynamic_type_map_init_reflect( &serverMap, &_library );
	type_server_init( &typeServer, &_library, &serverMap );
	type_client_init( &typeClient, &_library, &typeServerLink, &typeServer );
	dynamic_client_type_map_init( &clientMap, &_library, &typeClient );	

	int cid = type_map_get_id( &clientMap, &uint8_name );
	int sid = type_map_get_id( &serverMap, &uint8_name );	
 
    CPPUNIT_ASSERT( sid == cid );	
}

void TypeNetworkTest::testClientResolutionReverse()
{
	dynamic_type_map serverMap;
	type_server typeServer;
	type_client typeClient;
	dynamic_client_type_map clientMap;
	
	dynamic_type_map_init_reflect( &serverMap, &_library );
	type_server_init( &typeServer, &_library, &serverMap );
	type_client_init( &typeClient, &_library, &typeServerLink, &typeServer );
	dynamic_client_type_map_init( &clientMap, &_library, &typeClient );	

	type_map_map( &serverMap, 54, type_library_get_id( &_library, &sint32_name ) );
	int cid = type_map_get_library_id( &clientMap, 54 );
	int sid = type_library_get_id( &_library, &sint32_name );	
 
    CPPUNIT_ASSERT( sid == cid );	
}

void TypeNetworkTest::testClientResolutionLibraryId()
{
	dynamic_type_map serverMap;
	type_server typeServer;
	type_client typeClient;
	dynamic_client_type_map clientMap;
	
	dynamic_type_map_init_reflect( &serverMap, &_library );
	type_server_init( &typeServer, &_library, &serverMap );
	type_client_init( &typeClient, &_library, &typeServerLink, &typeServer );
	dynamic_client_type_map_init( &clientMap, &_library, &typeClient );	

	int cid = type_map_get_mapped_id( &clientMap, type_library_get_id( &_library, &uint32_name ) );
	int sid = type_map_get_id( &serverMap, &uint32_name );	
 
    CPPUNIT_ASSERT( sid == cid );	
}

void TypeNetworkTest::testClientResolutionReader()
{
	dynamic_type_map serverMap;
	type_server typeServer;
	type_client typeClient;
	dynamic_client_type_map clientMap;
	
	dynamic_type_map_init_reflect( &serverMap, &_library );
	type_server_init( &typeServer, &_library, &serverMap );
	type_client_init( &typeClient, &_library, &typeServerLink, &typeServer );
	dynamic_client_type_map_init( &clientMap, &_library, &typeClient );	

	type_reader* cReader = type_map_get_reader( &clientMap, type_map_get_id( &clientMap, &uint8_name ) );
	type_reader* sReader = type_map_get_reader( &serverMap, type_map_get_id( &serverMap, &uint8_name ) );	
 
    CPPUNIT_ASSERT( cReader->reader == sReader->reader );	
}

void TypeNetworkTest::testClientResolutionWriter()
{
	dynamic_type_map serverMap;
	type_server typeServer;
	type_client typeClient;
	dynamic_client_type_map clientMap;
	
	dynamic_type_map_init_reflect( &serverMap, &_library );
	type_server_init( &typeServer, &_library, &serverMap );
	type_client_init( &typeClient, &_library, &typeServerLink, &typeServer );
	dynamic_client_type_map_init( &clientMap, &_library, &typeClient );	

	type_writer* cWriter = type_map_get_writer( &clientMap, type_map_get_id( &clientMap, &uint8_name ) );
	type_writer* sWriter = type_map_get_writer( &serverMap, type_map_get_id( &serverMap, &uint8_name ) );	
 
    CPPUNIT_ASSERT( cWriter->writer == sWriter->writer );	
}
